﻿using System;
using System.IO;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;

namespace Job.Core.Common
{
    #region ILogger

    /// <summary>
    /// 日志记录器接口。
    /// </summary>
    public interface ILogger
    {
        /// <summary>
        /// 记录日志。
        /// </summary>
        /// <param name="message">要记录的消息字串。</param>
        void Log(string message);

        /// <summary>
        /// 记录日志。
        /// </summary>
        /// <param name="e">要记录的异常信息。</param>
        void Log(Exception e);
    }

    #endregion

    #region LoggerBase

    /// <summary>
    /// 日记抽象基类，建议日志记录器继承此类。
    /// </summary>
    public abstract class LoggerBase : ILogger
    {
        #region ILogger 成员

        /// <summary>
        /// 记录日志。
        /// </summary>
        /// <param name="message">要记录的消息字串。</param>
        public virtual void Log(string message)
        {
            if (string.IsNullOrEmpty(message))
                return;

            try
            {
                LogCore(message);
            }
            catch { }
        }

        /// <summary>
        /// 记录日志。
        /// </summary>
        /// <param name="e">要记录的异常信息。</param>
        public virtual void Log(Exception e)
        {
            if (e == null) return;

            Log(string.Format("======================================================================================{0}{1}\t{2}{0}{3}", Environment.NewLine, DateTime.Now, e.Message, e.StackTrace));
        }        

        #endregion

        /// <summary>
        /// 执行日志记录。
        /// </summary>
        /// <param name="message">要记录的消息字串。</param>
        public abstract void LogCore(string message);
    }

    #endregion

    #region FileLogger

    /// <summary>
    /// 文件日志记录器(将日志信息存储在本地文件中)。
    /// 可按日志产生时间记录到不同的文件中，详见构造函数 fileName 参数。
    /// </summary>
    public class FileLogger : LoggerBase
    {
        #region Properties

        private string fileName;

        private MatchCollection matchCollection;

        private static readonly Regex regex = new Regex("%[^%]+%", RegexOptions.Compiled);

        #endregion

        #region Constructor

        /// <summary>
        /// 初始化 FileLogger 类的新实例。
        /// </summary>
        /// <param name="fileName">存储日志的文件名(支持以 ~ 号开头的 Web 根目录表示)，可用%%包含字串将不同时间产生的日记记录到不同的文件中(如 ~/log%yyyy_MM_dd%.txt 可能会保存到 ~/log2010_08_08.txt)。</param>
        public FileLogger(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName");

            if (fileName.StartsWith("~") && HttpContext.Current != null)
                this.fileName = HttpContext.Current.Server.MapPath(fileName);
            else
                this.fileName = fileName;


            matchCollection = regex.Matches(this.fileName);            
        }

        #endregion

        #region Overrides

        /// <summary>
        /// 执行日志记录。
        /// </summary>
        /// <param name="message">要记录的消息字串。</param>
        public override void LogCore(string message)
        {
            string file = fileName;

            if (matchCollection.Count > 0)
            {
                //替换动态日期。
                foreach (Match match in matchCollection)
                    file = file.Replace(match.Value, DateTime.Now.ToString(match.Value.Trim('%')));
            }

            File.AppendAllText(file, message + Environment.NewLine, Encoding.UTF8);
        }

        #endregion
    }

    #endregion
}